package cn.kwq.pcsystem.concurrent;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.concurrent.Callable;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: kwq
 * @Date: 2023/03/14/10:21
 * @Description:
 */
@Slf4j
public class RedisLockUtils {
    /**
     * 获取到新的锁 使用非单例模式
     * @param redisTemplate
     * @return
     */
    public static RedisLock newLock(StringRedisTemplate redisTemplate){
        return new RedisLock(redisTemplate);
    }

    /**
     *  分布式并发环境下跑线程
     * @param lockName 锁唯一id
     * @param redisTemplate StringRedisTemplate
     * @param callable 线程
     * @return 执行方法返回的值
     * @param <V> 泛型
     */
    public static <V> V runWithLock(String lockName, StringRedisTemplate redisTemplate, Callable<V> callable) {
        RedisLock redisLock = RedisLockUtils.newLock(redisTemplate);
        //加锁
        try {
            redisLock.lock(lockName);
        } catch (Exception e) {
            log.debug("Get redisLock failed, lockName: {}" + lockName);
            throw new RuntimeException(e);
        }
        //业务逻辑
        try {
            return callable.call();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            //解锁
            redisLock.unlock(lockName);
            log.debug("Unlock successful, lockName: {}", lockName);
        }

    }
}
